//
// static.cpp
// 
// - This really should be called
// objects but it was taken up already
// 
// basically bots have attributes and
// use objects for drawing
//
// - This is the meat and potatoes of the
// artificial control
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#include <GL/gl.h>			// Header File For The OpenGL32 Library
#include <GL/glu.h>			// Header File For The GLu32 Library


#include "globals.h"
#include "camera.h"
#include "bot.h"
#include "objects.h"

#include "gldrawlib.h"
#include "plist.h"
#include "lights.h"

#undef CURRENT_PTR
#define CURRENT_PTR		StaticBotPtr

#undef CURRENT_OBJECT
#define CURRENT_OBJECT	StaticBot

#undef CURRENT_BOT
#define CURRENT_BOT		nest


#define MAX_NESTS			1

static CURRENT_PTR CreateSentinel(int bot_id);
static void RenderSentinel(CURRENT_PTR boid);
static void DestroySentinel(CURRENT_PTR b);
static void ProcessNest(CURRENT_PTR b);


static void DrawNests(void);
static void GenerateNests(void);
static void ShutdownNests(void);

GLfloat funk_ambient[] = { 0.0f, 0.0f, 0.8f, 1.0f };
GLfloat funk_diffuse[] = { 0.7f, 0.7f, 0.7f, 1.0f };
GLfloat funk_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat zno_shininess[] = { 0.0f };
GLfloat zlow_shininess[] = { 5.0f };
GLfloat zhigh_shininess[] = { 100.0f};
GLfloat zmat_emission[] = {0.3f, 0.3f, 0.2f, 0.0f};


// call 1. nest.generate
// call 2. nest.drawall
// call 3. nest.shutdown
DriverSentinel CURRENT_BOT =
{

	CreateSentinel,		// create
	DestroySentinel,	// destroy
	RenderSentinel,		// render
	ProcessNest,		// process

	GenerateNests,		// generate
	ShutdownNests,		// shutdown
	DrawNests,			// drawll

	NULL,				// ptr
	0			// max_items
};

//
// each ant gets 1000 food pieces
#define INITIAL_NEST_FOOD	(MAX_BOTS * INITIAL_ANT_FOOD)

//
// Generate Nests
//
static void GenerateNests(void)
{
	int index = 0;

	CURRENT_BOT.max_items = MAX_NESTS;

	// create the array of pointers
	CURRENT_BOT.objects = (CURRENT_OBJECT **)malloc(
			sizeof(CURRENT_OBJECT *));

	for (index = 0; index <  CURRENT_BOT.max_items; index++)
	{
		// this bordering on insane
		// allocate an array of bot pointers, duh for nest
		 CURRENT_BOT.objects[index] =  CURRENT_BOT.create(index);
		
	} // end of the for


	// Since I know first hand that there
	// is only one nest, create initial food offering
	// based on number of ants
	nest.objects[0]->food = INITIAL_NEST_FOOD;
	

} // end of the function

//
// Shutdown Nests
//
static void ShutdownNests(void)
{
	int index = 0;

	for (index = 0; index <  CURRENT_BOT.max_items; index++)
	{
		 CURRENT_BOT.destroy( CURRENT_BOT.objects[index]);

	} // end of the for 

} // end of the function


//
// Draw Nests
//
static void DrawNests(void)
{
	int index = 0;

	for (index = 0; index <  CURRENT_BOT.max_items; index++)
	{
		 CURRENT_BOT.process( CURRENT_BOT.objects[index]);

		 CURRENT_BOT.render( CURRENT_BOT.objects[index]);

	} // end of the for 

} // end of the function 


//
// Process Events
//
static void ProcessNest(CURRENT_PTR b)
{
	// just rotate
	b->rotation[1] += 0.5f;
	if (b->rotation[1] >= 360)
		b->rotation[1] -= 360;

} // end of the function


//
// Create bot
//
static CURRENT_PTR CreateSentinel(int bot_id)
{
	CURRENT_PTR		bot;

	bot = (CURRENT_PTR)malloc(sizeof(CURRENT_OBJECT));

	// I like to be extra careful
	ZeroMemory((CURRENT_PTR)bot, 
			sizeof(CURRENT_OBJECT));
	
	bot->position[0] = 0;
	bot->position[1] = 0;
	bot->position[2] = 0;


	bot->rotation[0] = 0;
	bot->rotation[1] = 0;
	bot->rotation[2] = 0;

	bot->size[0] = 2.0f;
	bot->size[1] = 2.0f;
	bot->size[2] = 2.0f;

	bot->color[0] = 1.0f;
	bot->color[1] = 1.0f;
	bot->color[2] = 0.0f;

	bot->state = ALIVE_STATE;

	return bot;

} // end of the function

//
// DestroyBot
//
static void DestroySentinel(CURRENT_PTR b)
{
	free(b);

} // end of the functino 



//
// RenderBot
//
static void RenderSentinel(CURRENT_PTR boid)
{
	BEGIN_BOT;
 
		// Translate then rotate
		glTranslatef(boid->position[0],boid->position[1],
				boid->position[2]);

		// rotate based on the ship struct
		glRotatef(boid->rotation[1], 0.0f, 1.0f, 0.0f);
		glRotatef(boid->rotation[0], 1.0f, 0.0f, 0.0f);
		glRotatef(boid->rotation[2], 0.0f, 0.0f, 1.0f);


#if 0
		//RenderBounds(0.0f, 0.0f, 1.5*boid->size[0]);
#endif

		// Scale accordingly
		glScalef(boid->size[0], boid->size[1], boid->size[2]);

		// This may or may not change the color
		glColor3f(boid->color[0], boid->color[1], boid->color[2]);

		// draw the object to screen
		//driver_objects[ANT_OBJECT]->render();

#if ENABLE_LIGHTS
		// set the material for this object
		setmaterial(funk_ambient, funk_diffuse, 
				funk_specular, zlow_shininess, zmat_emission);

#endif


		gluSphere(quadric, 0.5f, 18, 8);	// draw sphere for hood

	END_BOT;

} // end of the function 

